package com.bupt.ilink.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bupt.ilink.entity.User;
import com.bupt.ilink.entity.userManagement.DTO.UserMetaResponse;
import com.bupt.ilink.jwt.InvalidJwtAuthenticationException;
import com.bupt.ilink.jwt.JwtProperties;
import com.bupt.ilink.jwt.JwtTokenProvider;
import com.bupt.ilink.mapper.UserMapper;
import com.bupt.ilink.service.OssService;
import com.bupt.ilink.service.UserService;
import com.bupt.ilink.utils.R;
import com.bupt.ilink.utils.SnowflakeIdGenerator;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;


@Slf4j
@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private JwtProperties jwtProperties;

    @Autowired
    private OssService ossService;

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Lazy
    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 根据用户名查询用户信息
     *
     * @param username
     * @return org.springframework.security.core.userdetails.UserDetails
     * @author liuzheng
     * @create 2024-07-27
     **/
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        User user = userMapper.selectOne(queryWrapper);
        if (user == null) {
            return null;
        }
        return user;
    }

    public UserDetails loadUserByUserId(String userId) {
        String cleanUserId = userId.replace("\"", "");
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", cleanUserId);
        User user = userMapper.selectOne(queryWrapper);
        System.out.println("user: " + user);
        if (user == null) {
            return null;
        }
        return user;
    }

    /**
     * 创建新用户
     *
     * @param user
     * @return void
     * @author liuzheng
     * @create 2024-07-27
     **/
    @Override
    public void createUser(UserDetails user) {
        User newUser = (User) user;
        newUser.setPassword(passwordEncoder.encode(newUser.getPassword()));
        String uuid = UUID.randomUUID().toString().replace("-", "").substring(0, 10);
        String timestamp = String.valueOf(System.currentTimeMillis()).substring(5); // 获取时间戳的后8位
        String userId = uuid + timestamp;
        newUser.setUserId(userId);
        userMapper.insert(newUser);
    }

    @Override
    public void updateUser(UserDetails user) {
        User updateUser = (User) user;
        userMapper.updateById(updateUser);
    }

    @Override
    public void deleteUser(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        userMapper.delete(queryWrapper);
    }

    @Override
    public void changePassword(String oldPassword, String newPassword) {

    }

    @Override
    public void changePassword(String userId, String oldPassword, String newPassword) {
        // Implement password change logic if required
        User user = userMapper.selectById(userId);
        Assert.notNull(user, "User not found");
        if (passwordEncoder.matches(oldPassword, user.getPassword())) {
            user.setPassword(passwordEncoder.encode(newPassword));
            userMapper.updateById(user);
        } else {
            throw new IllegalArgumentException("Old password is incorrect");
        }
    }

    @Override
    public boolean userExists(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        return userMapper.selectCount(queryWrapper) > 0;
    }

    //查看用户的信息数据
    @Override
    public UserMetaResponse getUserMetaById(String userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            return null;
        }
        UserMetaResponse response = new UserMetaResponse();
        response.setUserId(userId);
        response.setNickname(user.getUsername());
        response.setSchool_name(user.getSchoolName());
        response.setEmail(user.getEmail());
        response.setSchool_id(user.getSchoolId());
        response.setUserIntroduction(user.getUserIntroduction());
        if (user.getUserImage() != null) {
            String ImageUrl = ossService.getFileUrl(user.getUserImage());
            if (ImageUrl != null) {
                response.setUserImage(ImageUrl);
            } else {
                log.error("用户{}的ImageUrl is null", userId);
            }
        }
//        response.setUserImage(user.getUserImage());
        response.setUserCollege(user.getUserCollege());
        response.setRealName(user.getRealname());
        response.setSex(user.getSex());
//        response.setUserStudentNumber(user.getUserStudentNumber());
        response.setUserGrade(user.getUserGrade());
        response.setUserMajor(user.getUserMajor());
        response.setUserMobile(user.getUserMobile());
        if (user.getUserCover() != null) {
            String CoverUrl = ossService.getFileUrl(user.getUserCover());
            if (CoverUrl != null) {
                response.setUserCover(CoverUrl);
            } else {
                log.error("用户{}的CoverUrl is null", userId);
            }
        }
        response.setLastLoginAt(user.getLastLoginAt());
//        response.setUserCover(user.getUserCover());
        return response;
    }

    //更新用户信息数据
    @Override
    public boolean updateUserMetaById(String userId, UserMetaResponse userMetaResponse) {
        User user = new User();
        BeanUtils.copyProperties(userMetaResponse, user);//快速将DTO的数据拷贝到user实体类中

        user.setUserId(userId);
//        if (Cover_path != null) {
//            user.setUserCover(Cover_path);
//        }
//        if (Image_path != null) {
//            user.setUserImage(Image_path);
//        }
        int result = userMapper.updateById(user);
        return result > 0;
    }

    //更新用户封面和头像
    public R updateUserImageById(User user, MultipartFile userCover, MultipartFile userImage) {
        try {
            log.info("user:{}", user);
            String Cover_path;
            String image_path;
            //不为空时上传封面和用户头像
            if (userCover != null) {
                Cover_path = uploadUserImage(userCover, user.getUserId());
                if (Cover_path != null) {
                    user.setUserCover(Cover_path);
                }
            }
            if (userImage != null) {
                image_path = uploadUserImage(userImage, user.getUserId());
                if (image_path != null) {
                    user.setUserImage(image_path);
                }
            }
            boolean isUpdated = userMapper.updateById(user) > 0;
            if (isUpdated) {
                return R.ok("修改用户图片成功", user.getUserId());
            } else {
                log.error("Failed to update user meta for {}", user.getUserId());
                //撤回对图片的导入
                //待增加

                return R.failure("User not found or update failed");
            }
        } catch (InvalidJwtAuthenticationException e) {
            return R.failure(e.getMessage());
        }

    }

    //上传用户照片
    public String uploadUserImage(MultipartFile file, String userId) {
        SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(3, 1);
        // 获取原始文件名
        String originalFilename = file.getOriginalFilename();

        // 获取文件扩展名
        String fileExtension = "";
        if (originalFilename != null && originalFilename.contains(".")) {
            fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        } else {
            log.error("文件解析扩展名出现错误：" + originalFilename);
            return null;
        }
        Long id = idGenerator.nextId();
        boolean uploadCover = ossService.uploadFile(file, "image/" + userId + "/", id + fileExtension);
        if (!uploadCover) {
            log.info("用户{}的图片上传失败", userId);
            return null;
        } else {
            //图片路径
            return "image/" + userId + "/" + id + fileExtension;
        }
    }

    public Map<String, Object> generateTokens(String userId) {
        Map<String, String> accessTokenData = new HashMap<>();
        accessTokenData.put("sub", userId);
        accessTokenData.put("type", "access");
        long accessTokenExpiresIn = jwtProperties.getValidityInMs();
        String accessToken = jwtTokenProvider.createToken(accessTokenData, accessTokenExpiresIn);

        Map<String, String> refreshTokenData = new HashMap<>();
        refreshTokenData.put("sub", userId);
        refreshTokenData.put("type", "refresh");
        long refreshTokenExpiresIn = jwtProperties.getRefreshValidityInMs();
        String refreshToken = jwtTokenProvider.createToken(refreshTokenData, refreshTokenExpiresIn);

        Map<String, Object> tokens = new HashMap<>();
        tokens.put("access_token", accessToken);
        tokens.put("refresh_token", refreshToken);
        tokens.put("token_type", "bearer");

        return tokens;
    }

    public void setTokenCookies(HttpServletResponse response, Map<String, Object> tokens) {
        String accessToken = (String) tokens.get("access_token");
        String refreshToken = (String) tokens.get("refresh_token");

        Cookie accessCookie = new Cookie("access_token_lf", accessToken);
        accessCookie.setPath("/");
        accessCookie.setHttpOnly(false);
        accessCookie.setSecure(false);
        accessCookie.setMaxAge((int) jwtProperties.getValidityInMs());
        response.addCookie(accessCookie);

        Cookie refreshCookie = new Cookie("refresh_token_lf", refreshToken);
        refreshCookie.setPath("/");
        refreshCookie.setHttpOnly(false);
        refreshCookie.setSecure(false);
        refreshCookie.setMaxAge((int) jwtProperties.getRefreshValidityInMs());
        response.addCookie(refreshCookie);
    }
}
